//
//  ALPullDownRefreshControl.swift
//  Swift01
//
//  Created by Miaoyang on 16/4/16.
//  Copyright © 2016年 Miaoyang. All rights reserved.
//

import UIKit


import SnapKit

/// 刷新控件的高度
private let ALPullDownRefreshControlHeight: CGFloat = 60

/// 刷新控件的状态 3种
enum ALPullDownRefreshControlStatus: Int {
    case Normal // 箭头朝下, 下拉刷新
    case PullToRefresh // 箭头朝上, 释放刷新
    case Refreshing // 正在刷新
}

/// 下拉刷新控件
class ALPullDownRefreshControl: UIView {
    
    // MARK: - 属性
    /// 01.定义i开始刷新的闭包
    var pullDownRefreshHandler: (() -> ())?
    
    private var superScrollView: UIScrollView?
    
    /// 当前状态, 默认为 Normal, 状态的切换是根据tableView.ContentOffest.y值来计算
    private var currentStatus: ALPullDownRefreshControlStatus = ALPullDownRefreshControlStatus.Normal {
        didSet {
            // 当状态切换了,根据不同状态设置不同内容
            switch currentStatus {
            case .Normal:
                ALPrint("Normal")
                // 隐藏风火轮
                fhlView.hidden = true
                
                // 显示箭头
                arrowView.hidden = false
                
                // 箭头回到初始的位置, 文字 下拉刷新
                messageLabel.text = "下拉刷新"
                UIView.animateWithDuration(ALDefautlAnimDuration, animations: { () -> Void in
                    self.arrowView.transform = CGAffineTransformIdentity
                })
                
            case .PullToRefresh:
                ALPrint("PullToRefresh")
                // 箭头旋转, 文字 释放刷新
                messageLabel.text = "释放刷新"
                
                UIView.animateWithDuration(ALDefautlAnimDuration, animations: { () -> Void in
                    self.arrowView.transform = CGAffineTransformMakeRotation(CGFloat(M_PI))
                })
            case .Refreshing:
                ALPrint("Refreshing")
                // 风火轮转, 文字 "正在刷新...", 不要滚动到导航栏下面
                // 文字 "正在刷新..."
                messageLabel.text = "正在刷新..."
                
                // 风火轮转
                fhlView.hidden = false
                arrowView.hidden = true
                
                // 添加动画
                let rotationAnim = CABasicAnimation(keyPath: "transform.rotation")
                rotationAnim.toValue = M_PI * 2
                rotationAnim.repeatCount = MAXFLOAT
                rotationAnim.duration = 0.5
                rotationAnim.removedOnCompletion = false
                
                // 给动画加forKey: 如果下次再添加一个和之前已经存在的动画,先停止之前的动画,在使用这次的动画, 防止动画重复添加
                fhlView.layer.addAnimation(rotationAnim, forKey: "rotationAnim")
                
                // 让tableView往下走HMPullDownRefreshControlHeight, 刷新控件就不会被导航栏挡住
                UIView.animateWithDuration(ALDefautlAnimDuration, animations: { () -> Void in
                    self.superScrollView?.contentInset.top += ALPullDownRefreshControlHeight
                })
                
                // 02.调用闭包,告诉别人开始刷新了
                pullDownRefreshHandler?()
            }
        }
    }
    
    /// 开始刷新
    func startRefreshing() {
        // 将状态切换到Refreshing
        currentStatus = .Refreshing
    }
    
    /// 完成刷新
    func endRefreshing() {
        // Refreshing切换到Normal
        currentStatus = .Normal
        
        // 只有是从Refreshing切换Normal才需要去 contentInset.top - HMPullDownRefreshControlHeight
        // 让tableView往上走HMPullDownRefreshControlHeight, 刷新控件就看不到了
        UIView.animateWithDuration(ALDefautlAnimDuration, animations: { () -> Void in
            self.superScrollView?.contentInset.top -= ALPullDownRefreshControlHeight
        })
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override init(frame: CGRect) {
        // 自己来里面定义frame,外面直接使用HMPullDownRefreshControl()
        let newFrame = CGRect(x: 0, y: -ALPullDownRefreshControlHeight, width: UIScreen.mainScreen().bounds.width, height: ALPullDownRefreshControlHeight)
        super.init(frame: newFrame)
        
        prepareUI()
    }
    
    private func prepareUI() {
        //        backgroundColor = UIColor.brownColor()
        
        // 添加控件
        addSubview(fhlView)
        addSubview(arrowView)
        addSubview(messageLabel)
        
        // 隐藏风火轮
        fhlView.hidden = true
        
        // 添加约束
        fhlView.snp_makeConstraints { (make) -> Void in
            make.centerX.equalTo(self).offset(-30)
            make.centerY.equalTo(self)
        }
        
        arrowView.snp_makeConstraints { (make) -> Void in
            make.center.equalTo(fhlView)
        }
        
        messageLabel.snp_makeConstraints { (make) -> Void in
            make.leading.equalTo(fhlView.snp_trailing).offset(10)
            make.centerY.equalTo(fhlView)
        }
    }
    
    // 当控件被添加到浮空件后会调用这个方法, 在这个时候可以拿到父控件
    // newSuperview: 父控件
    override func willMoveToSuperview(newSuperview: UIView?) {
        super.willMoveToSuperview(newSuperview)
        
        // 判断父控件是UIScrollView或其子类
        if let scrollView = newSuperview as? UIScrollView {
            superScrollView = scrollView
            
            // 使用KVO来监听scrollView的滚动
            // 要监听谁的属性,就用谁来调用
            // observer: 谁来处理监听事件
            // forKeyPath: 想监听的属性
            // options: 监听选项, 新值,老得值
            // context: 上下文
            superScrollView?.addObserver(self, forKeyPath: "contentOffset", options: [], context: nil)
        }
    }
    
    // KVO需要移除
    deinit {
        removeObserver(self, forKeyPath: "contentOffset")
    }
    
    /*
     Normal: contentOffset.y > -124  -100
     PullToRefresh: contentOffset.y < -124   -130
     
     -124 = -(superScrollView?.contentInset + HMPullDownRefreshControlHeight)
     */
    
    // 实现KVO的监听方法, 方法是固定的
    override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
        //        HMPrint("tableView滚动了: \(superScrollView?.contentOffset.y)")
        //        HMPrint("superScrollView?.contentInset: \(superScrollView?.contentInset)")
        
        // 用户拖拽才需要判断 Normal <==> PullToRefresh
        // dragging = 表示手在拖拽, false 松手了
        if superScrollView!.dragging {
            // 切换到Normal判断contentOffest.y,还需要判断当前状态是PullToRefresh
            if currentStatus == .PullToRefresh && superScrollView?.contentOffset.y > -(superScrollView!.contentInset.top + ALPullDownRefreshControlHeight) {
            ALPrint("切换到Normal")
                currentStatus = .Normal
            } else if currentStatus == .Normal && superScrollView?.contentOffset.y < -(superScrollView!.contentInset.top + ALPullDownRefreshControlHeight) {
                // 切换到PullToRefresh判断contentOffest.y,还需要判断当前状态是Normal
                ALPrint("切换到PullToRefresh")
                currentStatus = .PullToRefresh
            }
        } else if currentStatus == .PullToRefresh {
            // 用户松手了
            // 刷新状态, currentStatus = .PullToRefresh, 松手
            ALPrint("切换到Refreshing")
            currentStatus = .Refreshing
        }
    }
    
    // MARK: - 懒加载
    /// 箭头
    private lazy var arrowView: UIImageView = UIImageView(imageNamed: "tableview_pull_refresh")
    
    /// 风火轮
    private lazy var fhlView: UIImageView = UIImageView(imageNamed: "tableview_loading")
    
    /// 文字
    private lazy var messageLabel: UILabel = {
        let label = UILabel(fontSize: 14, textColor: UIColor.darkGrayColor())
        
        label.text = "下拉刷新"
        
        return label
    }()
}
